/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedBean.TX.CustomerIOTRPortal;

import java.text.ParseException;
import java.util.Date;
import javax.faces.bean.ManagedBean;
import java.util.List;
import java.util.Calendar;
import session.TX.*;
import helper.tx.*;
import Web_Helper.EmailSender;
import entity.tx.OutletReservation;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Properties;
import javax.ejb.EJB;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.primefaces.event.DateSelectEvent;
import session.CM.PortalManagementSB;

/**
 *
 * @author Chen Zhe
 */
@ManagedBean(name = "tableBookingMB")
@SessionScoped
public class TableBookingMB {

    @EJB
    private PortalManagementSB portalManagementSB;
    @EJB
    private AreaSBRemote areaBean;
    @EJB
    private OutletSBRemote outletBean;
    @EJB
    private CustomerReservationSBRemote customerReservationBean;
    private Date date;
    private String areaName;
    private Integer timeslot;
    private String comments;
    private Long reservationID;
    private String photo = " ";
    private List<Integer> timeslotList;
    private String message;
    private OutletReservation selectedReservation;
    private Integer diner;
    private List<Integer> dinerList;
    private String reservationStatus;

    /** Creates a new instance of TableBookingMB */
    public TableBookingMB() {
        initialize();
    }

    public void initialize() {
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
        System.out.println("Date!!:" + date);
    }

    public void updateDate(DateSelectEvent event) {
        System.out.println("Updating date...");
    }

    public void timeSlotList(ActionEvent event) {
        System.out.println("show" + this.getDate());

    }
    
    public void areaChange() throws ParseException{
        this.getTimeslots();
        this.getNumOfDiner();
    }

    public void getTimeslots() throws ParseException {
        Long outletId = getOutletIdFromSession();
        //get the day of the week g
        //  System.out.println("getTimesslots started!!!!!!!!!!!");
        System.out.println("im here~~");
        List timeslots2 = new ArrayList<Integer>();
        List timeslots3 = new ArrayList<Integer>();

        int dayInt;
        String day;
//        DateFormat formatter;
//        Date dateConverted;
        Calendar c = Calendar.getInstance();
        if (date == null) {
            System.out.println("Ajax hasn't updated date!!!!!!!!!!!!!!!");
        } else {
            System.out.println("DATE###" + date);
            // formatter = new SimpleDateFormat("MM/dd/yyyy");
            // dateConverted = (Date) formatter.parse(date);
            c.setTime(date);
            dayInt = c.get(Calendar.DAY_OF_WEEK);
            switch (dayInt) {
                case 1:
                    day = "Sunday";
                    break;
                case 2:
                    day = "Monday";
                    break;
                case 3:
                    day = "Tuesday";
                    break;
                case 4:
                    day = "Wednesday";
                    break;
                case 5:
                    day = "Thursday";
                    break;
                case 6:
                    day = "Friday";
                    break;
                case 7:
                    day = "Saturday";
                    break;
                default:
                    day = "Monday";
            }
            //     System.out.println("the day of the week is!!!" + day);
            //      System.out.println("the outlet id is!!!!" + getOutletId());

            List areaList = getAreaBean().getAllAreas(outletId);

            timeslots2 = getAreaBean().retrieveTime(getAreaBean().getAreaByAreaName(areaList, areaName).getTimeslots());

            ///    System.out.println("Have already got timeslots!" + timeslots2.toString());
            if (timeslots2 == null) {
                //     System.out.println("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
            }
        }
        //check for availabity, whether booking quota has exceeded the maxima quota
        for (Object o : timeslots2) {
            Integer i = (Integer) o;
            //transform the timeslot and date to a single Calendar timeslot
            DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
            Calendar ca = Calendar.getInstance();

            ca.setTime(date);
            //check if the selected date satisfy the lead time and booking window 
            Calendar beforeDate = getCalendar(getEndDateStr());
            Calendar afterDate = getCalendar(getStartDateStr());
            if (ca.before(afterDate) || ca.after(beforeDate)) {
                List<Integer> timeslots = new ArrayList<Integer>();
                setTimeslotList(timeslots);
            }
            // Integer Hour = new Integer(i.toString().substring(0, 2));
            // Integer Minute = new Integer(i.toString().substring(2, 4));
            // ca.set(Calendar.HOUR_OF_DAY, Hour);

            // ca.set(Calendar.MINUTE, Minute);
            //  System.out.println("The calendar we get from checking quota process is" + ca.getTime().toString());
            Boolean available = customerReservationBean.checkQuota(getCustEmailFromSession(), outletId, ca, areaName, i);
            //     System.out.println("The timeslot for " + i.toString() + " is " + available);
            if (available) {
                //        System.out.println("Have already got timeslots3!" + timeslots3.toString());
                timeslots3.add(i);
            }
        }

        List timeslots = new ArrayList();

        for (Object o : timeslots3) {
            Integer i = (Integer) o;
            SelectItem option = new SelectItem(i.toString(), i.toString());
            timeslots.add(option);
        }
        setTimeslotList((List<Integer>) timeslots);

    }

    public void getNumOfDiner() {
        List<Helper_Area> areaList = areaBean.getAllHelperAreas(getOutletIdFromSession());
        for (Helper_Area a : areaList) {
            if (a.getAreaName().equals(areaName)) {
                this.setDinerList(a.getNumDiners());
                break;
            }
        }
    }

    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
        //    System.out.println("The areaName is updated!! :" + areaName);
    }

    public void photoFilePath() {
        List areaList = getAreaBean().getAllAreas(getOutletIdFromSession());
        photo = "./Foodsage-war/member/../" + areaBean.getAreaByAreaName(areaList, areaName).getPathName();
        System.out.println("path%%" + photo);

    }

    /**
     * @return the areaNames
     */
    public List<SelectItem> getAreaNames() {
        List<Helper_Area> helperAreaList = new ArrayList<Helper_Area>();
        List<String> areaNames = new ArrayList<String>();
        helperAreaList = getAreaBean().getAllHelperAreas(getOutletIdFromSession());
        for (Object o : helperAreaList) {
            Helper_Area ha = (Helper_Area) o;
            areaNames.add(ha.getAreaName());
        }
        List<SelectItem> options = new ArrayList();
        for (String s : areaNames) {
            SelectItem option = new SelectItem(s, s);
            options.add(option);
        }

        return options;
    }

    public OutletSBRemote getOutletBean() {
        return outletBean;
    }

    public void setOutletBean(OutletSBRemote outletBean) {
        this.outletBean = outletBean;
    }

    public Integer getTimeslot() {
        return timeslot;
    }

    public void setTimeslot(Integer timeslot) {
        this.timeslot = timeslot;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }
    // This method will book the table, and return a booking result status, pending or successful

    public void getStatus() throws ParseException {
        Long outletId = getOutletIdFromSession();
        if (date == null) {
            System.out.println("DATEEEEEEEEEEEEEE ISSS" + date.toString());
            String status = "Status of Current Booking: Uncompleted";
            this.setReservationStatus(status);
        } else {
            String status = null;
            Boolean autoConfirm = outletBean.getAutoConfirm(outletId);
            //     System.out.println("the autoConfirm value in this outlet entitiy is!! " + autoConfirm.toString());
            //convert the String date and Integer timeslot into a single Calendar object tiemslot
            Calendar processTimeslot = Calendar.getInstance();
            //      System.out.println("the date value is!!" + date);

            processTimeslot.setTime(date);
            Integer Hour = timeslot / 100;
            //new Integer(timeslot.toString().substring(0, 2));

            processTimeslot.set(Calendar.HOUR_OF_DAY, Hour.intValue());
            Integer Minute = timeslot % 100;
            //new Integer(timeslot.toString().substring(2, 4));
            processTimeslot.set(Calendar.MINUTE, Minute.intValue());
            //   System.out.println("The final Calender object we get contains!!" + processTimeslot.getTime().toString());

            Long rID = customerReservationBean.AddUnconfirmedReservation(getCustEmailFromSession(), outletId, processTimeslot, timeslot, areaName, comments, diner);
            //if auto-confirmation  then reutrn sucessfull messagey


            if (autoConfirm) {

                //MAIL START

                String emailMessage = "Dear customer" + "," + "\n\n Your booking at " + outletId + " is successfull. Your reservation details are as follows:\n\n"
                        + "Date and Time: " + date + "  " + timeslot.toString() + "\nArea: " + areaName + "\nComments: " + comments
                        + "\n\n Thank you for using FoodSage.com";


                String senderEmail = portalManagementSB.getEmailFrom();
                String senderPassword = portalManagementSB.getEmailPassword();
                EmailSender emailsender = new EmailSender(senderEmail, senderPassword);
                String[] recepients = {getCustEmailFromSession()};

                try {
                    emailsender.postMail(recepients, "FoodSage Dining Reservation Confirmation", emailMessage, senderEmail);
                } catch (javax.mail.MessagingException e) {
                }

                //MAIL END


                System.out.print("Email Sent to Customer");

                //set status as return message
                status = "Your reservation is successful. The booking information will be sent to you through email.";
            } else {
                status = "Your reservation id is " + rID + ". Your reservation status is pending, and you will be notified via email once the status is confirmed."
                        + "If you want to cancel reservation, please enter your reservation ID before cancel reservation button.";
            }
            date = null;
            areaName = null;
            timeslot = null;
            comments = null;
            diner = null;
            this.setReservationStatus(status);
        }
    }

    public String getStartDateStr() {
//        System.out.println("Outlet id is:" + outletId);
        Calendar ca = Calendar.getInstance();
        //   System.out.println("The lead time is!!!!!!!!!!" + outletBean.getLeadTime(outletId));
//        System.out.println(outletBean.getLeadTime(outletId));
        ca.add(Calendar.DATE, outletBean.getLeadTime(getOutletIdFromSession()).intValue());
        return printCalendar(ca);
    }

    public String getEndDateStr() {
        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.DATE, (outletBean.getBookingWindow(getOutletIdFromSession()).intValue() + outletBean.getLeadTime(getOutletIdFromSession()).intValue()));
        return printCalendar(ca);
    }

    public Date getStartDate() {
//        System.out.println("Outlet id is:" + outletId);
        Calendar ca = Calendar.getInstance();
        //   System.out.println("The lead time is!!!!!!!!!!" + outletBean.getLeadTime(outletId));
//        System.out.println(outletBean.getLeadTime(outletId));
        ca.add(Calendar.DATE, outletBean.getLeadTime(getOutletIdFromSession()).intValue());
        return ca.getTime();
    }

    public Date getEndDate() {
        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.DATE, (outletBean.getBookingWindow(getOutletIdFromSession()).intValue() + outletBean.getLeadTime(getOutletIdFromSession()).intValue()));
        return ca.getTime();
    }

    public String printCalendar(Calendar ca) {
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        //     System.out.println("the calender we get here is" + sdf.format(ca.getTime()));
        return sdf.format(ca.getTime());
    }

    public Calendar getCalendar(String date) throws ParseException {
        DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
        Date d = formatter.parse(date);
        Calendar ca = Calendar.getInstance();
        ca.setTime(d);
        return ca;
    }

    public Long getReservationID() {
        return reservationID;
    }

    public void setReservationID(Long id) {
        this.reservationID = id;
    }

    public String getNoShowPenalty() {
        Long outletId = getOutletIdFromSession();
        System.out.println("It said that the outletID is!!!!!!:" + outletId);
        Double d = outletBean.getNoShowPenalty(outletId);
        String message;
        if (d == null) {
            message = "";
        } else if (d == 0) {
            message = "There will be no no-show-penalty fee.";
        } else {
            message = "The no show penalty fee is " + d.toString();
        }
        return message;
    }

    public AreaSBRemote getAreaBean() {
        return areaBean;
    }

    public void setAreaBean(AreaSBRemote areaBean) {
        this.areaBean = areaBean;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }

    public List<Integer> getTimeslotList() {
        return timeslotList;
    }

    public void setTimeslotList(List<Integer> timeslotList) {
        this.timeslotList = timeslotList;
    }

    public String getCustEmailFromSession() {
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("email").toString();
    }

    public Long getOutletIdFromSession() {
        return (Long) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("custOutletId");
    }

    public String getOutletNameFromSession() {
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("custOutletName").toString();
    }

    public String getStakeholderOutletName() {
        String oName = getOutletNameFromSession();
        String sName = outletBean.getStakeholderName(getOutletIdFromSession());
        return sName + ": " + oName;
    }

    public String getCustomerEmail() {
        return getCustEmailFromSession();
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public OutletReservation getSelectedReservation() {
        return selectedReservation;
    }

    public void setSelectedReservation(OutletReservation selectedReservation) {
        this.selectedReservation = selectedReservation;
    }

    public Integer getDiner() {
        return diner;
    }

    public void setDiner(Integer diner) {
        this.diner = diner;
    }

    public List<Integer> getDinerList() {
        return dinerList;
    }

    public void setDinerList(List<Integer> dinerList) {
        this.dinerList = dinerList;
    }

    public String getReservationStatus() {
        return reservationStatus;
    }

    public void setReservationStatus(String reservationStatus) {
        this.reservationStatus = reservationStatus;
    }
}
